﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.ComponentModel;
using Terralever.Facebook.UI.Design;
using System.Globalization;

namespace Terralever.Facebook.UI.FbmlControls
{
    /// <summary>
    /// Represents an fb:name element.
    /// </summary>
    [ToolboxData("<{0}:Name runat=\"server\" />")]
    [Designer("Terralever.Facebook.UI.Design.FbmlControls.FbNameDesigner, " + Constants.DESIGNER_LIB)]
    public class Name : FbmlControl
    {
        private bool m_firstOnly, m_lastOnly;

        /// <summary>
        /// Creates a new <see>Name</see> control.
        /// </summary>
        public Name()
        {
            Linked = true;
            UseYou = true;
            DisplayIfUserIsInaccessible = string.Empty;
        }

        /// <summary>
        /// Gets or sets the Facebook User ID of the user to display.  This property is required to be set.
        /// </summary>
        [FbmlRequired(IsRequired = true)]
        [Category(FbmlConstants.FBML_REQD_ATTR)]
        [Description("The Facebook User ID of the user for whom this name control is rendered.")]
        [DefaultValue(0)]
        public long FbUserID
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets whether to render only the user's first name.
        /// </summary>
        /// <remarks>
        /// <para>Setting this property to <see langword="true" /> will reset the <see>LastNameOnly</see>
        /// property to <see langword="false" />.  If both are set to <see langword="true" /> with declarative 
        /// syntax, this property takes precedence.</para>
        /// </remarks>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Show only the user's first name.")]
        [DefaultValue(false)]
        public bool FirstNameOnly
        {
            get { return m_firstOnly; }
            set
            {
                m_firstOnly = value;
                if (value) m_lastOnly = false;
            }
        }

        /// <summary>
        /// Gets or sets whether the user's name should link to his or her profile.
        /// </summary>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Link to the user's profile.")]
        [DefaultValue(true)]
        public bool Linked { get; set; }

        /// <summary>
        /// Gets or sets whether to render only the user's last name.
        /// </summary>
        /// <remarks>
        /// <para>Setting this property to <see langword="true" /> will reset the <see>FirstNameOnly</see>
        /// property to <see langword="false" />.  If both are set to <see langword="true" /> with declarative 
        /// syntax, the <see>FirstNameOnly</see> property takes precedence.</para>
        /// </remarks>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Show only the user's last name.")]
        [DefaultValue(false)]
        public bool LastNameOnly
        {
            get { return m_lastOnly; }
            set
            {
                m_lastOnly = value;
                if (value) m_firstOnly = false;
            }
        }

        /// <summary>
        /// Gets or sets whether to render the user's name as if it was possessive.
        /// </summary>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Makes the user's name posessive, e.g., \"Joe's\" instead of \"Joe\".")]
        [DefaultValue(false)]
        public bool Possessive { get; set; }

        /// <summary>
        /// Gets or sets whether to be reflexive if the <see>UseYou</see> property is set to <see langword="true" />.
        /// </summary>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Use \"yourself\" if the UseYou property is true.")]
        [DefaultValue(false)]
        public bool Reflexive { get; set; }

        /// <summary>
        /// Gets or sets whether to display the user's primary network.
        /// </summary>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Displays the primary network for the user.")]
        [DefaultValue(false)]
        public bool ShowNetwork { get; set; }

        /// <summary>
        /// Gets or sets whether to display "you" if the logged-in user matches the FbUserID property.
        /// </summary>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Displays \"you\" if the logged-in user matches the FbUserID property.")]
        [DefaultValue(true)]
        public bool UseYou { get; set; }

        /// <summary>
        /// Gets or sets the alternate text to display if the logged-in user cannot access the specified user.
        /// </summary>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Alternate text to display if the logged-in user cannot access the specified user.")]
        [DefaultValue("")]
        public string DisplayIfUserIsInaccessible { get; set; }

        /// <summary>
        /// Gets or sets whether to capitalize "You" or its variants if the <see>UseYou</see> property is <see langword="true" />
        /// </summary>
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("Capitalizes \"You\" if the UseYou property is true and the logged-in user matches the FbUserID property.")]
        [DefaultValue(false)]
        public bool CapitalizeYou { get; set; }
        
        /// <summary>
        /// Gets or sets the Facebook ID of the subject of the sentence where this name is the object of the verb of the sentence.
        /// </summary> 
        [Category(FbmlConstants.FBML_OPT_ATTR)]
        [Description("The Facebook ID of the subject of the sentence where this name is the object of the verb of the sentence.")]
        [DefaultValue(false)]
        public long SubjectID { get; set; }

        /// <inheritdoc />
        protected internal override string ElementName
        {
            get { return FbmlConstants.FB_NAME; }
        }

        /// <inheritdoc />
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            if (FbUserID == 0)
                throw new RequiredFbmlAttributeNotSetException("FbUserID", FbUserID);

            writer.AddAttribute("uid", FbUserID.ToString(CultureInfo.InvariantCulture));
            if (!Linked)
                writer.AddAttribute("linked", FbmlConstants.FALSE);

            if (FirstNameOnly)
                writer.AddAttribute("firstnameonly", FbmlConstants.TRUE);
            else if (LastNameOnly)
                writer.AddAttribute("lastnameonly", FbmlConstants.TRUE);

            if (Possessive)
                writer.AddAttribute("possessive", FbmlConstants.TRUE);
            if (Reflexive)
                writer.AddAttribute("reflexive", FbmlConstants.TRUE);
            if (ShowNetwork)
                writer.AddAttribute("shownetwork", FbmlConstants.TRUE);
            if (!UseYou)
                writer.AddAttribute("useyou", FbmlConstants.FALSE);
            if (!string.IsNullOrEmpty(DisplayIfUserIsInaccessible))
                writer.AddAttribute("ifcantsee", DisplayIfUserIsInaccessible, true);
            if (CapitalizeYou)
                writer.AddAttribute("capitalize", FbmlConstants.TRUE);
            if (SubjectID != 0)
                writer.AddAttribute("subjectid", SubjectID.ToString(CultureInfo.InvariantCulture));

            base.AddAttributesToRender(writer);
        }
    }
}
